package de.se.ludoapp.gaming;

import de.se.ludoapp.response.GameFieldResponse;
import de.se.ludoapp.response.GameListResponse;
import de.se.ludoapp.response.GameResponse;
import de.se.ludoapp.response.HighscoreResponse;
import de.se.ludoapp.response.PlayerDiceResponse;
import de.se.ludoapp.response.RequestingPlayerListResponse;
import de.se.ludoapp.response.ReturncodeResponse;
import de.se.ludoapp.response.UserLoginResponse;

//TODO Sachen Importieren fuer die Throws Exceptions

/**
 * This is the interface between Ludoserver and -client.
 * 
 * @author Felix, Marlen
 */
public interface LudoSystem {

	/**
	 * Operation to login for the user with username and password
	 * 
	 * @param username
	 * @param password
	 * @return TODO Exceptions erstellen
	 * @throws PasswortUngueltigException
	 * @throws UsernameUngueltigException
	 */
	public UserLoginResponse login(String username, String password);

	/**
	 * Operation to logout. This closed the session from the user.
	 * 
	 * @param sessionID
	 */
	public void logout(User user);

	/**
	 * Operation to create a new user account.
	 * 
	 * @param username
	 *            with new username
	 * @param password
	 *            and desired password TODO creat Exceptions
	 * @return
	 * @throws usernameUngueltigException
	 */
	public UserLoginResponse register(String username, String password);

	/**
	 * Operation to dice
	 * 
	 * @param sessionId
	 * @param gameId
	 */
	public PlayerDiceResponse dice(int sessionId, int gameId);

	/**
	 * List of all OPEN games
	 */
	public GameListResponse getFreeGames();

	/**
	 * List of all RUNNING games
	 */
	public GameListResponse getRunningGames();

	/**
	 * Method to create a new Game Table
	 * 
	 * @param sessionId
	 */
	public GameResponse openNewGame(int sessionId);

	/**
	 * Closed a game completly
	 * 
	 * @param game
	 */
	public void closeGame(Game game);

	/**
	 * Check if there are other users, which want to join the game
	 * 
	 * @param sessionId
	 * @param gameId
	 * @return
	 */
	public RequestingPlayerListResponse handleRequests(int sessionId, int gameId);

	/**
	 * Get the highscores of the game (currently only Ludo)
	 * 
	 * @param gameName
	 * @return
	 */
	public HighscoreResponse getHighscore(String gameName);

	/**
	 * Accept an user Request for a player of game
	 * 
	 * @param sessionId
	 * @param userName
	 * @param gameId
	 * @return
	 */
	public GameResponse allowUserToEnterTheGame(int sessionId, String userName,
			int gameId);

	/**
	 * This method starts the game. Only the yellow Player is authorized to do
	 * so.
	 * 
	 * The gameBoard is initialized during this method. Futhermore, the status
	 * is set as running and the remaining diceAttempts of the
	 * YellowPlayer(always the beginner) are set to 3.
	 * 
	 * @param sessionId
	 * @param gameId
	 * @return
	 */
	public GameFieldResponse startGame(int sessionId, int gameId);

	/**
	 * If the available Games are listed, the user can select a game he wants to
	 * enter.
	 * 
	 * @param sessionId
	 * @param gameId
	 * @return
	 */
	public ReturncodeResponse enterExistingGame(int sessionId, int gameId);

	/**
	 * Is called from requesting Player after he asked for permission to enter
	 * the Game
	 * 
	 * @param sessionId
	 * @param gameId
	 * @return returnCode = 0 if user was accepted, returnCode = 1 if permission
	 *         was denied. If 0, GameTO-Object is delivered
	 */
	public GameResponse isTheRequestingPlayerAccepted(int sessionId, int gameId);

	/**
	 * Is called from requesting player who does not want to play anymore, when
	 * the waiting time is over.
	 * 
	 * @param sessionId
	 * @param gameId
	 * @return returnCode = 0 if deleted was successful, 1 if it was not and the
	 *         game has already started (=> if he leaves despite this fact, he
	 *         will get negative points for the game
	 */
	public ReturncodeResponse removeRequestingPlayerForGame(int sessionId,
			int gameId);

	/**
	 * Updates on GameField?
	 * 
	 * @param gameId
	 * @param gameField
	 * @return
	 */
	public GameFieldResponse askForUpdatesOnGameField(int gameId,
			int[] gameField);

	/**
	 * Move selected Character on Gameboard.
	 * 
	 * @param gameId
	 * @param sessionId
	 * @param gameFieldIndex
	 * @param diceResult
	 * @return
	 */
	public GameFieldResponse moveCharacter(int gameId, int sessionId,
			int gameFieldIndex, int diceResult);

	/**
	 * Is called from player red, blue and green if they were accepted for the
	 * game.
	 * 
	 * @param sessionId
	 * @param gameId
	 * @return returnCode = 0 if the game has started. returnCode = 1 if the
	 *         game is not started yet
	 */
	public GameFieldResponse isTheGameStarted(int sessionId, int gameId);

	/**
	 * get an game by id
	 * 
	 * @param gameId
	 * @return
	 */
	public GameResponse getGameById(int gameId);

	public ReturncodeResponse leaveRunningGame(int sessionId, int gameId);

	public ReturncodeResponse leaveOpenGame(int sessionId, int gameId);
}
